﻿using System.ComponentModel;
using System.Windows;
using System.Windows.Interactivity;
using ZOIL.Framework.Presentation;

namespace ZOIL.Library.Devices
{
    public class ZInputBehavior<T> : Behavior<T>, INotifyPropertyChanged where T : ZInformationLandscape
    {
        #region dependency properties

        #region IsEnabled

        public bool IsEnabled
        {
            get { return (bool)GetValue(IsEnabledProperty); }
            set { SetValue(IsEnabledProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsEnabled.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof(bool), typeof(ZInputBehavior<T>), new PropertyMetadata(true, OnIsEnabledChanged));

        private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var inputBehavior = d as ZInputBehavior<T>;
            if (inputBehavior == null) return;

            inputBehavior.OnIsEnabledChanged((bool)e.OldValue, (bool)e.NewValue);
        }

        protected virtual void OnIsEnabledChanged(bool oldIsEnabled, bool newIsEnabled)
        {
        }

        #endregion

        #region IsPanningEnabled

        public bool IsPanningEnabled
        {
            get { return (bool)GetValue(IsPanningEnabledProperty); }
            set { SetValue(IsPanningEnabledProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsPanningEnabled.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsPanningEnabledProperty =
            DependencyProperty.Register("IsPanningEnabled", typeof(bool), typeof(ZInputBehavior<T>), new PropertyMetadata(true, OnIsPanningEnabledChanged));

        private static void OnIsPanningEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var inputBehavior = d as ZInputBehavior<T>;
            if (inputBehavior == null) return;

            inputBehavior.OnIsPanningEnabledChanged((bool)e.OldValue, (bool)e.NewValue);
        }

        protected virtual void OnIsPanningEnabledChanged(bool oldIsPanningEnabled, bool newIsPanningEnabled)
        {
        }

        #endregion

        #region IsZoomingEnabled

        public bool IsZoomingEnabled
        {
            get { return (bool)GetValue(IsZoomingEnabledProperty); }
            set { SetValue(IsZoomingEnabledProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsZoomingEnabled.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsZoomingEnabledProperty = DependencyProperty.Register("IsZoomingEnabled", typeof(bool), typeof(ZInputBehavior<T>), new PropertyMetadata(true, OnIsZoomingEnabledChanged));

        private static void OnIsZoomingEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var inputBehavior = d as ZInputBehavior<T>;
            if (inputBehavior == null) return;

            inputBehavior.OnIsZoomingEnabledChanged((bool)e.OldValue, (bool)e.NewValue);
        }

        protected virtual void OnIsZoomingEnabledChanged(bool oldIsZoomingEnabled, bool newIsZoomingEnabled)
        {
        }

        #endregion

        #region IsClickZoomEnabled

        public bool IsClickZoomEnabled
        {
            get { return (bool)GetValue(IsClickZoomEnabledProperty); }
            set { SetValue(IsClickZoomEnabledProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsClickZoomEnabled.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsClickZoomEnabledProperty = DependencyProperty.Register("IsClickZoomEnabled", typeof(bool), typeof(ZInputBehavior<T>), new PropertyMetadata(true, OnIsClickZoomEnabledChanged));

        private static void OnIsClickZoomEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var inputBehavior = d as ZInputBehavior<T>;
            if (inputBehavior == null) return;

            inputBehavior.OnIsClickZoomEnabledChanged((bool)e.OldValue, (bool)e.NewValue);
        }

        protected virtual void OnIsClickZoomEnabledChanged(bool oldIsClickZoomEnabled, bool newIsClickZoomEnabled)
        {
        }

        #endregion

        #endregion

        #region properties

        #region CurrentWindow

        /// <summary>
        /// Gets the current Window in which the landscape lies
        /// </summary>
        protected Window CurrentWindow
        {
            get
            {
                return Window.GetWindow(AssociatedObject);
            }
        }

        #endregion

        #endregion

        #region event helpers

        #region ClickZoom method

        protected virtual void RaiseClickZoomEvent(FrameworkElement zoomTarget)
        {
            if (zoomTarget == null) return;
            AssociatedObject.ZoomOnto(zoomTarget, false, true);
            zoomTarget.RaiseEvent(new RoutedEventArgs(ZInformationLandscape.ClickZoomEvent, zoomTarget));
        }

        #endregion

        #endregion

        #region Implementation of INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}
